package informationplatform.guidepost




import java.text.DecimalFormat;

import informationplatform.UserProfile;
import informationplatform.milestone.Milestone;
import informationplatform.milestone.MilestoneFunction;
import informationplatform.milestone.MilestoneFunctionPartake;
import informationplatform.milestone.MilestoneFunctionType;
import informationplatform.product.GuidepostObject
import informationplatform.product.ProductGuidepost
import informationplatform.product.ProductHistory;
import informationplatform.product.ProductVersion;
import informationplatform.product.GuidepostStatus;
import informationplatform.task.Task;
import informationplatform.product.SupportingSoftware

import java.text.SimpleDateFormat
//import java.util.Calendar;
import java.util.Date;

class GuidepostCommonController {
	def productService
	def productHistoryService
	def guidepostService
	def parameterService
	def milestoneFunctionService

	static SimpleDateFormat dateFormat = new SimpleDateFormat('yyyy-MM-dd')
	// def nextDay =  dateFormat.parse( dateFormat.format( new Date() ) )+1
	DecimalFormat df = new DecimalFormat("#.#");
	// -------------------------------------------路标子系统历史------------------------------------------------start
	def historyHome(){
		[targetId: params.targetId, targetType:params.targetType]
	}

	def listHistories(){
		//当直接传入路标id，则应找需要审核的内容
		def after=null
		if(params.guidepostId){
			def guidepostAuditedHis = ProductHistory.withCriteria{
				eq('targetType', 'GUIDEPOST')
				eq('targetId', params.guidepostId.toLong())
				eq('toSt',GuidepostStatus.AUDITED)

				order("createdDate", "desc")
			}

			if(guidepostAuditedHis){
				after = guidepostAuditedHis[0]
			}
		}

		session.guidepost_history_targetType = params.targetType
		session.guidepost_history_targetName = params.targetName

		def histories = ProductHistory.withCriteria{

			//当直接传入路标id，则应找需要审核的内容
			if(params.guidepostId){
				or{
					and{
						eq('targetType', 'GUIDEPOST')
						eq('targetId', params.guidepostId.toLong())
					}

					and{
						eq('targetType', 'PVERSION')
						ilike('treeId', params.guidepostId + "-%")
					}
				}

				if(after){
					gt('createdDate', after.audited.createdDate)
				}

			}else{

				if(params.targetType && params.targetType != ''){
					eq('targetType', params.targetType)
				}

				if(params.targetName && params.targetName != ''){
					def targetNm = params.targetName.trim()
					ilike('targetName', "%${targetNm}%")
				}

				if(params.targetId && params.targetId != ''){
					eq('targetId', params.targetId.toLong())
				}
				'in'('targetType', GuidepostObject.values()*.name())
			}


			//-------------------------------------排序 START
			def sortIndex=0
			def sortStr
			def feildStr
			while(params."sort[${sortIndex}][dir]"){
				sortStr = params."sort[${sortIndex}][dir]"
				feildStr =  params."sort[${sortIndex}][field]"
				order(feildStr, sortStr)
				sortIndex++
			}
			//-------------------------------------排序 END


			//-------------------------------------分页 START
			order("createdDate", "desc")
			firstResult params.skip?.toInteger() ?: 0
			maxResults params.pageSize?.toInteger() ?: 100
			//-------------------------------------分页 END
		}

		def total = ProductHistory.withCriteria{
			projections{ count('id') }

			//当直接传入路标id，则应找需要审核的内容
			if(params.guidepostId){
				or{
					and{
						eq('targetType', 'GUIDEPOST')
						eq('targetId', params.guidepostId.toLong())
					}

					and{
						eq('targetType', 'PVERSION')
						ilike('treeId', params.guidepostId + "-%")
					}
				}

				if(after){
					gt('createdDate', after.audited.createdDate)
				}

			}else{

				if(params.targetType && params.targetType != ''){
					eq('targetType', params.targetType)
				}

				if(params.targetName && params.targetName != ''){
					def targetNm = params.targetName.trim()
					ilike('targetName', "%${targetNm}%")
				}

				if(params.targetId && params.targetId != ''){
					eq('targetId', params.targetId.toLong())
				}
				'in'('targetType', GuidepostObject.values()*.name())
			}
		}[0]

		println total + " " + histories.size()

		render(contentType:"text/json"){
			[total:total, histories: array{
					histories.each{
						row(id: it.id,
								targetType: GuidepostObject.valueOf(it.targetType).label,
								targetTypeName: it.targetType,
								targetId: it.targetId,
								targetName: it.targetName,
								statusChange: ("${it.fromSt?.label?:''} -> ${it.toSt?.label?:''}"),
								changedContent: it.changedContent?:'',
								createdBy: it.audited.createdBy,
								createdDate: it.audited.createdDate.format('yyyy-MM-dd HH:mm:ss')
								)
					}
				}
			]
		}
	}


	def viewStatusPath(){
		def histories = productHistoryService.getChangePath(params.targetId, params.targetType)

		[histories: histories]
	}

	def ajaxViewStatusPath(){
		def histories = productHistoryService.getChangePath(params.targetId, params.targetType)

		render(contentType:"text/json"){
			[histories: array{
					histories.each{
						row(id: it.id,
								targetTypeName: it.targetType,
								targetId: it.targetId,
								targetName: it.targetName,
								status: it.toSt?.label?:'',
								createdBy: it.audited.createdBy,
								createdDate: it.audited.createdDate.format('yy-MM-dd')
								)
					}
				}
			]
		}
	}

	def exportGuidepostReport(){
		ProductHistory his = ProductHistory.get(params.id.toLong())

		String fileName = "路标_${his.targetName}_变更报表"
		fileName =  new String(fileName.getBytes("gb2312"), "ISO8859-1")
		response.setHeader("Content-disposition", "attachment; filename=${fileName}.xls")

		def out = response.outputStream
		def wb = productHistoryService.exportGuidepostReport(params.targetId.toLong(), null, null)

		//写回文件内容
		wb.write(out)

		out.flush()
		out.close()
	}
	// -------------------------------------------路标子系统历史------------------------------------------------end
	/**
	 * 初始化右边的联动下拉框和左边树div的几个参数<br>
	 *
	 * @return
	 */
	def viewGuidepostObject(){
		def focusObjectId
		def focusObjectType
		def product
		def guidepost

		if(params.viewObjectId && params.viewObjectType){//跳转到本页面时, 参数都齐全
			focusObjectId = params.viewObjectId.toLong()
			focusObjectType = GuidepostObject.valueOf(params.viewObjectType)

			//首先要找出树结构的顶级对象: 路标
			if(GuidepostObject.GUIDEPOST == focusObjectType){
				guidepost = ProductGuidepost.get(focusObjectId)
			}else if(GuidepostObject.PVERSION == focusObjectType){
				guidepost = ProductVersion.get(focusObjectId).guidepost
			}else if(GuidepostObject.MILESTONE == focusObjectType){
				guidepost = Milestone.get(focusObjectId).guidepost
			}else if(GuidepostObject.FUNCTION == focusObjectType){
				guidepost = MilestoneFunction.get(focusObjectId).guidepost
			}

			product = guidepost.product

		}else{
			//取默认的产品
			product = session.currProduct
			if(!product){
				def relevantProducts = productService.findVisibleProducts(session.user)
				if(relevantProducts){
					product = relevantProducts[0]
				}
			}

			if(product){
				//取默认路标
				guidepost = session.currGuidepost

				//---------------------------------------------------------
				// 在默认路标从来没有的情况下，更新session, userProfile中的路标
				// UpdatedBy: LJ, 13-11-1
				//---------------------------------------------------------
				if(!guidepost){
					def guideposts = ProductGuidepost.findAllByProduct(product)
					if(guideposts){
						guidepost = guideposts[0]
						//session设定默认路标
						session.currGuidepost = guidepost
						def userPro = UserProfile.findByUser(session.user)
						userPro.defaultGuidepost = guidepost
						userPro.save()
					}
				}

				focusObjectId = guidepost?.id
				focusObjectType = GuidepostObject.GUIDEPOST
			}
		}

		[focusObjectId: focusObjectId, focusObjectType: focusObjectType, productId:product?.id, guidepostId: guidepost?.id, viewChildren: params.viewChildren]
	}

	/**
	 * 展示整棵树
	 *
	 * @return
	 */
	def viewGuidepostObjectTree(){
		def res = []
		if(params.focusObjectId == null || params.focusObjectId == ""){
			render(contentType:"text/json"){ res }
			return
		}

		def focusObjectId = params.focusObjectId.toLong()
		def focusObjectType = GuidepostObject.valueOf(params.focusObjectType)

		//----------------- 需要展开的节点---------------start
		def guidepostOpen
		def pverionOpen
		def milestoneOpen
		def funcOpen
		//首先要找出树结构的顶级对象: 路标
		if(GuidepostObject.GUIDEPOST == focusObjectType){
			guidepostOpen = ProductGuidepost.get(focusObjectId)

		}else if(GuidepostObject.PVERSION == focusObjectType){
			pverionOpen = ProductVersion.get(focusObjectId)
			guidepostOpen = pverionOpen.guidepost

		}else if(GuidepostObject.MILESTONE == focusObjectType){
			milestoneOpen = Milestone.get(focusObjectId)
			pverionOpen = milestoneOpen.pversion
			guidepostOpen = milestoneOpen.guidepost

		}else if(GuidepostObject.FUNCTION == focusObjectType){
			funcOpen = MilestoneFunction.get(focusObjectId)
			milestoneOpen = funcOpen.milestone
			pverionOpen = funcOpen.pversion
			guidepostOpen = funcOpen.guidepost
		}

		//session设定默认路标
		session.currGuidepost = guidepostOpen
		def userPro = UserProfile.findByUser(session.user)
		userPro.defaultGuidepost = guidepostOpen
		userPro.save()
		//----------------- 需要展开的节点---------------end

		//首先判别有没有点击树的节点, 没有点击即没有id = objecType_id时显示树根对象
		if(!params.id){
			res << [id:"GUIDEPOST_${guidepostOpen.id}", text:guidepostOpen.name,hasChildren: ProductVersion.countByGuidepost(guidepostOpen)>0, expanded:true, imageUrl:"${resource(dir: 'images/icons', file: 'guidepost.png')}"]

		}else{

			def ids = params.id.split("_")//Branch ID
			def branchNodeId = ids[1].toLong()
			def branchNodeType = GuidepostObject.valueOf(ids[0])
			def hasCh = true


			if(GuidepostObject.GUIDEPOST == branchNodeType){
				def pversions = ProductVersion.withCriteria{
					guidepost{idEq(branchNodeId)}
					order('createdDate','asc')
				}

				pversions.each{
					def expanded=false
					if(pverionOpen && pverionOpen.id == it.id){
						expanded = true
					}

					res << [id:"PVERSION_${it.id}", text:"${it.name}", hasChildren:Milestone.countByPversion(it)>0, expanded:expanded, imageUrl:"${resource(dir: 'images/icons', file: 'old_versions.png')}", expireFlag: guidepostService.expire(it)]
				}
			}

			if(GuidepostObject.PVERSION == branchNodeType){
				def milestones = Milestone.withCriteria{
					pversion{idEq(branchNodeId)}
					order('no','asc')
				}

				milestones.each{
					def expanded=false
					if(milestoneOpen && milestoneOpen.id == it.id){
						expanded = true
					}
					res << [id:"MILESTONE_${it.id}", text:"${it.name}", hasChildren:MilestoneFunction.countByMilestone(it)>0, expanded:expanded, imageUrl:"${resource(dir: 'images/icons', file: 'milestone.png')}", expireFlag: guidepostService.expire(it)]
				}
			}

			if(GuidepostObject.MILESTONE == branchNodeType){
				def funcs=[]
				funcs.addAll(MilestoneFunction.withCriteria{
					milestone{idEq(branchNodeId)}
					order('planCompleteDate','asc')
					ne('functionType', MilestoneFunctionType.USER_FUNCTION)
				})

				funcs.addAll( MilestoneFunction.withCriteria{
					milestone{idEq(branchNodeId)}
					order('createdDate','asc')
					eq('functionType', MilestoneFunctionType.USER_FUNCTION)
				})

				funcs.each{

					if(it.functionType == MilestoneFunctionType.USER_FUNCTION){
						res << [id:"FUNCTION_${it.id}", text:"${it.name}", hasChildren:false, expanded:false, imageUrl:"${resource(dir: 'images/icons', file: 'function.png')}", expireFlag: guidepostService.expire(it)]
					}else{
						res << [id:"FUNCTION_${it.id}", text:"${it.name}", hasChildren:false, expanded:false, imageUrl:"${resource(dir: 'images/icons', file: 'function_auto.png')}", expireFlag: guidepostService.expire(it)]
					}
				}
			}
		}

		render(contentType:"text/json"){ res }
	}

	// -------------------------------------------浏览对象详情-----------------------------------------START
	/**
	 * 点击树结构节点时，统一入口函数
	 *
	 * @return
	 */
	def switchView(){
		def ids = params.id.split("_")
		def branchNodeId = ids[1]
		def branchNodeType = GuidepostObject.valueOf(ids[0])

		if(GuidepostObject.MILESTONE == branchNodeType){
			redirect(action: "viewMilestone", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.PVERSION == branchNodeType){
			redirect(action: "viewVersion", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.FUNCTION == branchNodeType){
			redirect(action: "viewFunction", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.GUIDEPOST == branchNodeType){
			redirect(action: "viewGuidepost", id: branchNodeId, params:[_: params._])
			return
		}
	}

	def viewMilestone(){
		def ms = Milestone.get(params.id.toLong())
		def nextDay =  dateFormat.parse( dateFormat.format( new Date() ) )+1
		def planNum = MilestoneFunction.withCriteria {
			projections{ count('id') }
			milestone{ idEq(ms.id) }
			//	lt('planCompleteDate', nextDay)
		}[0]

		def actualNum = MilestoneFunction.withCriteria {
			projections{ count('id') }
			milestone{ idEq(ms.id) }

			//lt('planCompleteDate', nextDay)
			eq('status',GuidepostStatus.COMPLETED)
			//	between('actualCompleteDate', startDate, endDate)
		}[0]


		def rate = null
		if(planNum ){
			if(actualNum){
				rate = Double.parseDouble(df.format(actualNum/planNum*100));
			}else{
				rate = 0
			}
		}
		def currRate = (rate!=null? (rate + '%'):'/')

		[milestone:ms,currRate:currRate]
	}
	def viewVersion(){
		def ver = ProductVersion.get(params.id.toLong())
		def nextDay =  dateFormat.parse( dateFormat.format( new Date() ) )+1
		def planNum = MilestoneFunction.withCriteria {
			projections{ count('id') }
			pversion{ idEq(ver.id) }
			//	lt('planCompleteDate', nextDay)
		}[0]

		def actualNum = MilestoneFunction.withCriteria {
			projections{ count('id') }
			pversion{ idEq(ver.id) }
			//lt('planCompleteDate', nextDay)
			eq('status',GuidepostStatus.COMPLETED)
			//lt('actualCompleteDate', new Date())
		}[0]

		def rate=null
		if(planNum ){
			if(actualNum){
				rate = Double.parseDouble(df.format(actualNum/planNum*100));
			}else{
				rate = 0
			}
		}
		def currRate = (rate!=null? (rate + '%'):'/')
		def softwares = SupportingSoftware.withCriteria{ eq('productVersion', ver) }

		[pversion:ver,currRate:currRate, softwares: softwares]
	}
	def viewFunction(){

		def func = MilestoneFunction.get(params.id.toLong())

		//找task时, 有引用别人则用别人的task
		def task = Task.find{
			milestoneFunc==(func.referFunc?:func) && parent==null
		}

		def referedfuncs = MilestoneFunction.withCriteria{
			referFunc{idEq(params.id.toLong())}
		}

		//找参与专项
		def milestoneFunctionPartakes = MilestoneFunctionPartake.withCriteria{
			eq('milestoneFunction', (func.referFunc?:func))
		}

		[id: params.id, task: task, referFunc: func.referFunc, func: (func.referFunc?:func),self:func, referedfuncs: referedfuncs, milestoneFunctionPartakes:milestoneFunctionPartakes]
	}

	def viewGuidepost(){
		def guidepost = ProductGuidepost.get(params.id.toLong())

		def changeNum = ProductHistory.withCriteria {
			projections{ count('id') }
			eq('targetType',GuidepostObject.GUIDEPOST.name())
			eq('targetId',guidepost.id)
			eq('fromSt',GuidepostStatus.SUBMIT_REVIEW)
			eq('toSt',GuidepostStatus.REVIEWED)
		}[0]
		if(changeNum>0){
			changeNum -=1
		}else{
			changeNum = 0
		}
		[guidepost:guidepost, changeNum:changeNum]
	}
	// -------------------------------------------浏览对象详情-----------------------------------------END


	// -------------------------------------------浏览对象子列表-----------------------------------------START
	/**
	 * 点击树结构节点时，统一入口函数
	 *
	 * @return
	 */
	def switchViewGrid(){
		def ids = params.id.split("_")
		def branchNodeId = ids[1]
		def branchNodeType = GuidepostObject.valueOf(ids[0])

		if(GuidepostObject.MILESTONE == branchNodeType){
			redirect(action: "viewFunctionGrid", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.PVERSION == branchNodeType){
			redirect(action: "viewMilestoneGrid", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.FUNCTION == branchNodeType){
			redirect(action: "viewTaskGrid", id: branchNodeId, params:[_: params._])
			return
		}

		if(GuidepostObject.GUIDEPOST == branchNodeType){
			redirect(action: "viewVersionGrid", id: branchNodeId, params:[_: params._])
			return
		}
	}

	def viewMilestoneGrid(){
		if(!params.parentId){
			[id: params.id]
		}else{
			def milestones = Milestone.withCriteria{
				pversion{idEq(params.parentId.toLong())}

				//-------------------------------------排序 START
				def sortIndex=0
				def sortStr
				def feildStr
				while(params."sort[${sortIndex}][dir]"){
					sortStr = params."sort[${sortIndex}][dir]"
					feildStr =  params."sort[${sortIndex}][field]"
					order(feildStr, sortStr)
					sortIndex++
				}
				//-------------------------------------排序 END

				firstResult params.skip?.toInteger() ?: 0
				maxResults params.pageSize?.toInteger() ?: 100
			}

			render(contentType:"text/json"){
				[total:milestones.size(),
							rows: array{
								milestones.each{
									row(id: it.id,
											name: it.name,
											description: it.description,
											no: it.no,
											startDate: it.startDate?.format('yyyy-MM-dd'),
											endDate: it.endDate?.format('yyyy-MM-dd'),
											status: it.status.label)
								}
							}
						]
			}

		}
	}

	def viewVersionGrid(){
		if(!params.parentId){
			[id: params.id]
		}else{
			def pversions = ProductVersion.withCriteria{
				guidepost{idEq(params.parentId.toLong())}

				//-------------------------------------排序 START
				def sortIndex=0
				def sortStr
				def feildStr
				while(params."sort[${sortIndex}][dir]"){
					sortStr = params."sort[${sortIndex}][dir]"
					feildStr =  params."sort[${sortIndex}][field]"
					order(feildStr, sortStr)
					sortIndex++
				}
				//-------------------------------------排序 END

				firstResult params.skip?.toInteger() ?: 0
				maxResults params.pageSize?.toInteger() ?: 100
			}

			render(contentType:"text/json"){
				[total:pversions.size(),
							rows: array{
								pversions.each{
									row(id: it.id,
											name: it.name,
											functionDesc: it.functionDesc,
											director: it.director.realName,
											creator: it.director.realName,
											planCompleteDate: it.planCompleteDate?.format('yyyy-MM-dd'),
											actualCompleteDate: it.actualCompleteDate?.format('yyyy-MM-dd'),
											pilotscaleExperimentDate: it.pilotscaleExperimentDate?.format('yyyy-MM-dd'),
											realeseDate: it.realeseDate?.format('yyyy-MM-dd'),
											status: it.status.label
											)
								}
							}
						]
			}

		}
	}

	def viewFunctionGrid(){
		if(!params.parentId){
			[id: params.id]
		}else{
			def funcs = MilestoneFunction.withCriteria{
				milestone{idEq(params.parentId.toLong())}

				//-------------------------------------排序 START
				def sortIndex=0
				def sortStr
				def feildStr
				while(params."sort[${sortIndex}][dir]"){
					sortStr = params."sort[${sortIndex}][dir]"
					feildStr =  params."sort[${sortIndex}][field]"
					order(feildStr, sortStr)
					sortIndex++
				}
				//-------------------------------------排序 END

				firstResult params.skip?.toInteger() ?: 0
				maxResults params.pageSize?.toInteger() ?: 100
			}

			render(contentType:"text/json"){
				[total:funcs.size(),
							rows: array{
								funcs.each{

									row(id: it.id,
											name: it.name,
											description: it.description,
											type: it.type,
											bigType: it.bigType,
											functionType: it.functionType?.label,
											requirementOrigin: it.requirementOrigin?:'',
											requirementOriginLink: it.requirementOriginLink?:'',
											testCase: it.testCase?:'',
											testCaseLink: it.testCaseLink?:'',
											rdmTask: it.rdmTask?:'',
											rdmTaskLink: it.rdmTaskLink?:'',
											requirementPromiseCompleteDate: it.requirementPromiseCompleteDate?.format('yyyy-MM-dd'),
											needSupportRequirementDoc: it.needSupportRequirementDoc==true?'是':'',
											needCheckCode: it.needCheckCode==true?'是':'',
											supportDesignDocType: it.supportDesignDocType?:'',
											reviewLevel: it.reviewLevel?:'',
											needReviewDesignDoc: it.needReviewDesignDoc==true?'是':'',
											needSupportPrototype: it.needSupportPrototype==true?'是':'',
											needUnitTesting: it.needUnitTesting==true?'是':'',
											startDate: it.startDate?.format('yyyy-MM-dd'),
											actualCompleteDate: it.actualCompleteDate?.format('yyyy-MM-dd'),
											status: it.status.label,
											creator: it.creator.realName,
											planCompleteDate: it.planCompleteDate?.format('yyyy-MM-dd'),
											referFunc: it.referFunc?.id?:'',
											referFuncName: it.referFunc?.name?:''
											)
								}
							}
						]
			}

		}
	}
	def viewTaskGrid(){
		def func = MilestoneFunction.get(params.id.toLong())

		def task = Task.find{
			milestoneFunc==func && parent==null
		}

		[id: params.id, task: task, referFunc: func.referFunc, func:func]
	}

	// -------------------------------------------浏览对象子列表-----------------------------------------END

	def findVisibleProducts(){
		def relevantProducts = productService.findVisibleProducts(session.user)

		render(contentType:"text/json"){
			array{
				relevantProducts.each{
					row(id: it.id,
							name: it.name
							)
				}
			}
		}
	}


	def ajaxExsits(){
		def focusObjectId = params.viewObjectId.toLong()
		def focusObjectType = GuidepostObject.valueOf(params.viewObjectType)
		def obj

		//首先要找出树结构的顶级对象: 路标
		if(GuidepostObject.GUIDEPOST == focusObjectType){
			obj = ProductGuidepost.get(focusObjectId)
		}else if(GuidepostObject.PVERSION == focusObjectType){
			obj = ProductVersion.get(focusObjectId)
		}else if(GuidepostObject.MILESTONE == focusObjectType){
			obj = Milestone.get(focusObjectId)
		}else if(GuidepostObject.FUNCTION == focusObjectType){
			obj = MilestoneFunction.get(focusObjectId)
		}

		def re=[st:'no', msg:'该对象已被删除!']
		if(obj){
			re.st = "yes"
		}

		render(contentType:"text/json"){ re }
	}


	//------------------------------------路标操作流程按钮------------------------------------start

	def submitAudit(){
		def re =[st:'success', msg:'保存成功!']

		try{
			guidepostService.submitAudit(params.id)
		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"保存失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}

	def audit(){
		def re =[st:'success', msg:'保存成功!']

		try{
			guidepostService.audit(params.id, params.isAccept)
		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"保存失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}


	def submitReview(){
		def re =[st:'success', msg:'保存成功!']

		try{
			guidepostService.submitReview(params.id)
		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"保存失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}


	def review(){
		def re =[st:'success', msg:'保存成功!']

		try{
			guidepostService.review(params.id, params.isAccept)
		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"保存失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}

	def completeFunc(){
		def re =[st:'success', msg:'更改成功!']

		try{
			guidepostService.completeFunc(params.id)
		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"更改失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}

	def batchCompleteFunc(){
		def re =[st:'success', msg:'更改成功!']

		try{
			guidepostService.batchCompleteFunc(params.ids)

		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"更改失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}
	}


	def batchEdit(){
		[reviewLevelOptions: parameterService.getOptions('REVIEW_LEVEL'), ids:params.ids]
	}

	def submitBatchEdit(){
		//1
		if(!params.type_check){
			params.remove('type')
		}

		//2
		if(!params.bigType_check){
			params.remove('bigType')
		}

		//3
		if(!params.requirementOrigin_check){
			params.remove('requirementOrigin')
		}

		//4
		if(!params.requirementOriginLink_check){
			params.remove('requirementOriginLink')
		}

		//5
		if(!params.requirementPromiseCompleteDate_check){
			params.remove('requirementPromiseCompleteDate')
		}

		//6
		if(!params.startDate_check){
			params.remove('startDate')
			params.remove('planCompleteDate')
		}

		//7
		if(!params.reviewLevel_check){
			params.remove('reviewLevel')
		}

		//8
		if(!params.supportDesignDocType_check){
			params.remove('supportDesignDocType')
		}

		//9
		if(!params.partakesUserIds_check){
			params.remove('partakesUserIds')
		}

		//10
		if(!params.needSupportRequirementDoc_check){
			params.remove('needSupportRequirementDoc')
		}

		//11
		if(!params.needCheckCode_check){
			params.remove('needCheckCode')
		}

		//12
		if(!params.needReviewDesignDoc_check){
			params.remove('needReviewDesignDoc')
		}

		//13
		if(!params.needSupportPrototype_check){
			params.remove('needSupportPrototype')
		}

		//14
		if(!params.needUnitTesting_check){
			params.remove('needUnitTesting')
		}




		def re =[st:'success', msg:'更改成功!']

		try{
			def ids = params.ids.split(',')
			ids.each{
				params.id = it
				milestoneFunctionService.updateForBatch(params)
			}

		}catch(Exception e){
			log.error(e.getMessage(), e)

			re =[st:'failed', msg:"更改失败: ${e.getMessage()}"]
		}

		render(contentType:'text/json'){re}

	}
	//------------------------------------路标操作流程按钮------------------------------------end
}
